

import sqlite3 as lite

from dexen.system.server import db
from dexen.system.common.meta import JobMeta
from dexen.system.common.base import Individual


ZIP_NAME = "job_def.zip"
SCHEMA_NAME = "job_def"


class ArchiveMgr(object):
    def __init__(self, job_meta):      
        assert isinstance(job_meta, JobMeta)
        self.job_meta = job_meta
        self._archive_job()
    
    def _execute_stmt(self, stmt, params):
        conn = db.get_connection()
        c = conn.cursor()
        assert isinstance(c, lite.Cursor)
        c.execute(stmt, params)
        conn.commit()
        c.close()
        
    def _archive_job(self):
        jm = self.job_meta
        assert isinstance(jm, JobMeta)
        stmt = "INSERT INTO Job VALUES (?,?,?,?)"
        params = (jm.get_id(), jm.get_name(), jm.creation_time, jm.get_zip())
        self._execute_stmt(stmt, params)

    def _job_id(self):
        jm = self.job_meta
        assert isinstance(jm, JobMeta)
        return jm.get_id()
    
    def _archive_ind(self, ind):
        assert isinstance(ind, Individual)
        archived = ind._get_archived()
        for filename, content in archived.items():
            stmt = "INSERT INTO Archive VALUES (?,?,?,?)"
            params = (ind.__id__, filename, buffer(content), self._job_id()) 
            self._execute_stmt(stmt, params)
        ind._strip_archived() # TODO: Important
    
    def archive_inds(self, inds):
        for ind in inds:
            self._archive_ind(ind)

    def archive_master(self, archived):
        pass

    def _get_query_result(self, query, params):
        conn = db.get_connection()
        c = conn.cursor()
        assert isinstance(c, lite.Cursor)
        c.execute(query, params)
        conn.commit()
        res = c.fetchall()
        c.close()
        return res

    def get_ind_archive(self, ind_id, name):
        query = """SELECT Content FROM Archive, Job WHERE IndId = ? AND 
                Archive.Name = ? AND Archive.JobId = ? AND Job.Id = ?"""
        params = (ind_id, name, self._job_id(), self._job_id())
        rows = self._get_query_result(query, params)
        assert len(rows) == 1 
        return str(rows[0]['Content'])
    
    def get_ind_archive_all(self, ind_id):
        query = """SELECT Archive.Name, Content FROM Archive, Job WHERE 
                IndId = ? AND Archive.JobId = ? AND Job.Id = ?"""
        params = (ind_id, self._job_id(), self._job_id())
        rows = self._get_query_result(query, params)
        res = {}
        for row in rows:
            res[row['Name']] = str(row['Content'])
        return res
    
    def get_ind_archive_names(self, ind_id):
        query = """SELECT Archive.Name FROM Archive, Job WHERE IndId = ? 
                AND Archive.JobId = ? AND Job.Id = ?"""
        params = (ind_id, self._job_id(), self._job_id())
        rows = self._get_query_result(query, params)
        res = [x['Name'] for x in rows]
        return res
    
    def delete_all(self):
        #The method is called, when the corresponding job is deleted by the user.
        pass


#===============================================================================
# TESTING
#===============================================================================
def test():
    schema_meta = JobMeta(None, "HAHA")
    arc_mgr = ArchiveMgr(schema_meta)
    ind = Individual()
    ind.__id__ = 1560
    ind.archive_data("ali.txt", range(25))
    ind.archive_data("veli.txt", "Nasilsin koc hahahahahaha")
    arc_mgr.archive_data(ind)

def main():
    test()

if __name__ == "__main__":
    main()

     